import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormControl } from '@angular/forms';
import { NzMessageService } from 'ng-zorro-antd';

import { BusinessService } from '@shared/services/business.service';
import { StoreDataService } from '../../store-data.service';
import { StoreCommonReq } from '@shared/interfaces/store';
import { StoreNewBaseClass } from '../baseClass';
import { makeAllControlDirty } from 'app/utils/helpers';
import { Country, Currency } from '@shared/interfaces/common'
import {
  emailReg,
  storeNumReg,
  storeNameENReg,
  storeNumMaxLength,
  storeNameMaxLength,
  storeNameENMaxLength,
  detailAddressMaxLength,
  usernameMaxLength,
  contactNameMaxLength,
  emailMaxLength,
  alphanumericAndSymbolsReg,
  storePostalCodeReg,
  cityMaxLength,
} from 'app/utils/contraints'
import { EBizLevel } from '@shared/enums'
import { NumConflictAsyncValidator } from 'app/utils/form-control.validator'
import { IMCC } from '@shared/components/mcc-select/mcc-select.interface'
import { I18NService } from '@core'

@Component({
  selector: 'app-store-new-base',
  templateUrl: './base.component.html',
  styleUrls: ['../../../../shared/styles/new-page-form.less'],
})
export class StoreNewBaseComponent extends StoreNewBaseClass implements OnInit {
  validateForm: FormGroup
  selectedCountry: Country
  selectedMCC: IMCC
  isCurrencyMultiple = false

  errorTips = {}

  constructor(
    public fb: FormBuilder,
    public storeStore: StoreDataService,
    private msg: NzMessageService,
    private bizService: BusinessService,
    private i18n: I18NService,
  ) {
    super(fb, storeStore)
  }

  get storeNumCtrl(): FormControl {
    return this.validateForm.get('storeNum') as FormControl
  }

  get selectedCurrency(): Currency | Currency[] {
    const { currencies } = this.storeStore.value.store.common
    if (this.isCurrencyMultiple && currencies.length) {
      return this.storeStore.value.store.common.currencies[0]
    }

    return currencies
  }

  set selectedCurrency(value: Currency | Currency[]) {
    if (Array.isArray(value)) {
      this.storeStore.value.store.common.currencies = value
      return
    }

    const currencies = this.storeStore.value.store.common.currencies || []
    if (!currencies.length) {
      currencies.push(value)
      return
    }

    currencies[0] = value
  }

  ngOnInit(): void {
    this.initBaseData()
    this.initValidateForm()
  }

  initBaseData(): void {
    this.storeStore.value$.subscribe(store => (this.store = store))
  }

  initValidateForm(): void {
    const { insCode, storeNum, storeName, storeNameEN, contact, address, mcc } = this.storeStore.value.store.common

    let city = ''

    if (address) {
      if (address.nationAll) {
        this.selectedCountry = {
          name: address.nationAll.name,
          codeAlpha3: address.nationAll.codeAlpha3,
        }
      }

      city = address.city
    }

    if (mcc) {
      const replaceMcc = mcc as IMCC
      this.selectedMCC = {
        mccCode: replaceMcc.mccCode,
        mccEnName: replaceMcc.mccEnName,
      }
    }
    this.validateForm = this.fb.group({
      storeNum: [
        storeNum,
        [Validators.maxLength(storeNumMaxLength), Validators.pattern(storeNumReg)],
        [NumConflictAsyncValidator(this.bizService, insCode, EBizLevel.Store)],
      ],
      storeName: [storeName, [Validators.required, Validators.maxLength(storeNameMaxLength)]],
      storeNameEN: [
        storeNameEN,
        [Validators.required, Validators.maxLength(storeNameENMaxLength), Validators.pattern(storeNameENReg)],
      ],
      currencies: [this.selectedCurrency, [Validators.required]],
      mcc: [this.selectedMCC, [Validators.required]],
      contactName: [contact.name, [Validators.required, Validators.maxLength(contactNameMaxLength)]],
      contactEmail: [
        contact.email,
        [Validators.required, Validators.maxLength(emailMaxLength), Validators.pattern(emailReg)],
      ],
      country: [this.selectedCountry, [Validators.required]],
      city: [
        city,
        [Validators.required, Validators.maxLength(cityMaxLength), Validators.pattern(alphanumericAndSymbolsReg)],
      ],
      zipCode: [
        address.zipCode,
        [Validators.required, Validators.maxLength(usernameMaxLength), Validators.pattern(storePostalCodeReg)],
      ],
      detailAddress: [address.address, [Validators.required, Validators.maxLength(detailAddressMaxLength)]],
    })
    this.initErrorTips()
  }

  initErrorTips() {
    this.errorTips = {
      storeNum: {
        maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: storeNumMaxLength }),
        pattern: this.trans('VALIDATION.PATTERN.ALPHANUMERIC_SYMBOLS_ONLY'),
        isNumTaken: this.trans('VALIDATION.CODE_EXISTS', { name: this.trans('GENERAL.STORE.NUM') }),
      },
      storeName: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.STORE.NAME') }),
        maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: storeNameMaxLength }),
      },
      storeNameEN: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.STORE.NAME_EN') }),
        maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: storeNameENMaxLength }),
        pattern: this.trans('VALIDATION.PATTERN.ALPHANUMERIC_SYMBOLS_ONLY'),
      },
      currencies: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.INFO.TRANSACTION_CURRENCY') }),
      },
      mcc: {
        required: this.trans('VALIDATION.REQUIRED_SELECT', { name: 'MCC' }),
      },
      contactName: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.INFO.CONTACT_NAME') }),
        maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: contactNameMaxLength }),
      },
      contactEmail: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.INFO.EMAIL') }),
        maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: emailMaxLength }),
        pattern: this.trans('VALIDATION.PATTERN.EMAIL'),
      },
      country: {
        required: this.trans('VALIDATION.REQUIRED_SELECT', { name: this.trans('GENERAL.INFO.COUNTRY_REGION') }),
      },
      city: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.INFO.CITY') }),
        maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: cityMaxLength }),
        pattern: this.trans('VALIDATION.PATTERN.ENGLISH_STATEMENT'),
      },
      zipCode: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.INFO.POSTAL_CODE') }),
        maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: usernameMaxLength }),
        pattern: this.trans('VALIDATION.PATTERN.NUMBER_ONLY'),
      },
      detailAddress: {
        required: this.trans('VALIDATION.REQUIRED', { name: this.trans('GENERAL.INFO.ADDRESS') }),
        maxlength: this.trans('VALIDATION.MAX_LENGTH', { length: detailAddressMaxLength }),
      },
    }
  }

  checkValid(): boolean {
    if (this.validateForm.valid) {
      this.pushDataToStore()
      this.msg.success(this.trans('GENERAL.NOTIFICATION.VALIDATION_SUCCESS'))
      return true
    }

    makeAllControlDirty(this.validateForm)
    this.msg.error(this.trans('GENERAL.NOTIFICATION.VALIDATION_FAIL'))
    return false
  }

  pushDataToStore(): void {
    this.store.store.common = this.fullfilData(this.validateForm)
    this.storeStore.updateValue(this.store)
  }

  onCurrenciesChange(currency: Currency | Currency[]): void {
    this.selectedCurrency = currency
  }

  onCountryChange(country: Country): void {
    this.selectedCountry = country
  }

  onMCCChange(mcc: IMCC): void {
    this.selectedMCC = mcc
  }

  isMerNumTaken(): boolean {
    return this.validateForm.get('storeNum').hasError('isMerNumTaken')
  }

  trans(key: string, params?: Object): string {
    return this.i18n.fanyi(key, params)
  }

  private fullfilData(form: FormGroup): StoreCommonReq {
    const common = this.storeStore.value.store.common
    common.storeNum = form.value.storeNum
    common.storeName = form.value.storeName
    common.storeNameEN = form.value.storeNameEN
    common.currencies = Array.isArray(this.selectedCurrency) ? this.selectedCurrency : [this.selectedCurrency]
    common.mcc = form.value.mcc ? form.value.mcc : ''
    common.contact.name = form.value.contactName
    common.contact.email = form.value.contactEmail
    common.address.nation = form.value.country && form.value.country.codeAlpha3
    common.address.nationAll = form.value.country
    common.address.city = form.value.city
    common.address.address = form.value.detailAddress
    common.address.zipCode = form.value.zipCode
    return common
  }
}
